// vim:ft=cpp

/////////////
// FUNCTOR //
/////////////

/*{*/

template< class __class__ >
Functor< __class__ >::Functor(
		__class__* anInstance,
		void* ( __class__::*aFunction )( void* ),
		void* someArgs) :
	m_instance( anInstance ),
	m_thr( new pthread_t ),
	m_function( aFunction ),
	m_args( someArgs )
{
}

template< class __class__ >
Functor< __class__ >::~Functor()
{
	delete m_thr;
}

template< class __class__ >
void* Functor< __class__ >::start()
{
	if ( m_instance != NULL && m_function != NULL )
	{
		return (m_instance->*m_function)( m_args );
	}

	return NULL;
}

template< class __class__ >
int Functor< __class__ >::startThreaded(
		const pthread_attr_t* attr )
{
	int res = pthread_create( m_thr, attr, &Functor::apply, this );
	pthread_detach( *m_thr );
	return res;
}

template< class __class__ >
void* Functor< __class__ >::apply( void* aFunctor )
{
	return ((Functor< __class__ >*) aFunctor)->start();
}

/*}*/

////////////////////
// DESTROYFUNCTOR //
////////////////////

/*{*/

template< class __class__ >
DestroyFunctor< __class__ >::DestroyFunctor(
		__class__* anInstance,
		void* ( __class__::*aFunction )( void* ),
		void* someArgs,
		bool threadedLaunch,
		pthread_t* thr,
		pthread_attr_t* attr) :
	Functor< __class__ >( anInstance, aFunction, someArgs ),
	threaded( threadedLaunch ),
	thread( thr ),
	attribute( attr )
{
}

template< class __class__ >
DestroyFunctor< __class__ >::~DestroyFunctor()
{
	if ( threaded )
	{
		Functor< __class__ >::startThreaded( thread, attribute );
		pthread_detach( *thread );
	}
	else
	{
		Functor< __class__ >::start();
	}
}

/*}*/

